<!--
 * @Author: panghu chenjh@datamargin.com
 * @Date: 2024-04-03 17:48:13
 * @LastEditors: panghu chenjh@datamargin.com
 * @LastEditTime: 2024-05-04 15:44:42
 * @FilePath: \zheye\src\components\ValidateInput.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <div class="validate-input-container pb-3">
    <input v-if="tag == 'input'" class="form-control" :class="{'is-invalid': inputRef.error}" v-model="inputRef.val" @blur="validateInput" v-bind="$attrs">
    <textarea v-else class="form-control" :class="{'is-invalid': inputRef.error}" v-model="inputRef.val" @blur="validateInput" v-bind="$attrs"></textarea>
    <span class="invalid-feedback" v-if="inputRef.error">
      {{ inputRef.message }}
    </span>
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType, reactive, onMounted, computed } from 'vue'
import { emitter } from './ValidateForm.vue'
const emialReg = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
type ValidatorFn = () => boolean
interface RuleType {
  type: 'required' | 'email' | 'custom',
  message: string,
  validator?: ValidatorFn
}
export type RulesType = RuleType[]
export type Tag = 'input' | 'textarea'

export default defineComponent({
  name: 'ValidateInput',
  props: {
    rules: Array as PropType<RulesType>,
    modelValue: String,
    tag: {
      type: String as PropType<Tag>,
      default: 'input'
    }
  },
  inheritAttrs: false,
  setup (props, context) {
    const inputRef = reactive({
      val: computed({
        get: () => props.modelValue || '',
        set: (value: string) => {
          context.emit('update:modelValue', value)
        }
      }),
      error: false,
      message: ''
    })
    const validateInput: ValidatorFn = () => {
      if (props.rules) {
        const allPassed = props.rules.every(rule => {
          let passed = true
          inputRef.message = rule.message
          switch (rule.type) {
            case 'required':
              passed = (inputRef.val.trim() !== '')
              break
            case 'email':
              passed = emialReg.test(inputRef.val)
              break
            case 'custom':
              passed = (rule.validator && rule.validator()) || false
              break
            default:
              break
          }
          return passed
        })
        inputRef.error = !allPassed
        return allPassed
      }
      return true
    }
    onMounted(() => {
      emitter.emit('form-item-created', validateInput)
    })
    return {
      inputRef,
      validateInput
    }
  }
})
</script>

<style scoped>

</style>
